<?php

// @formatter:off
/**
 * @file WCActiveTagFewTags.php
 * @author Alejandro Dario Simi
 * @date $Date: 2014-05-04 01:33:52 +0000 (Sun, 04 May 2014) $
 *
 * $Id: WCActiveTagFewTags.php 111 2014-05-04 01:33:52Z daemonraco@gmail.com $
 * $URL: http://wcomix.googlecode.com/svn/trunk/includes/activetags/WCActiveTagFewTags.php $
 */
// @formatter:on

global $wcDefaults;
if(!isset($wcDefaults["class-WCActiveTagFewTags"])) {
	$wcDefaults["class-WCActiveTagFewTags"] = array();
}
if(!isset($wcDefaults["class-WCActiveTagFewTags"]["limit"])) {
	$wcDefaults["class-WCActiveTagFewTags"]["limit"] = 5;
}
if(!isset($wcDefaults["class-WCActiveTagFewTags"]["group-limits"])) {
	$wcDefaults["class-WCActiveTagFewTags"]["group-limits"] = array();
}

/**
 * class WCActiveTagHook
 */
class WCActiveTagFewTags extends WCActiveTagHook {
	/**
	 * @var WCConnection Database pointer shortcut.
	 */
	protected $_db = false;
	/**
	 * @var string Database tables' prefix shortcut.
	 */
	protected $_dbprefix = false;
	/**
	 * @var WCTag
	 */
	protected $_noTag = false;
	/**
	 * Class constructor
	 */
	public function __construct() {
		// @{
		$this->_canIt["add"]["CL"] = false;
		$this->_canIt["add"]["CX"] = defined("__CRON__");
		$this->_canIt["add"]["DI"] = false;
		$this->_canIt["add"]["IM"] = defined("__CRON__");
		$this->_canIt["add"]["TA"] = false;

		$this->_canIt["remove"]["CL"] = false;
		$this->_canIt["remove"]["DI"] = false;
		$this->_canIt["remove"]["TA"] = false;
		// @}
		//
		// Loading global pointers.
		global $wcDatabaseAccess;
		//
		// Loading shortcuts.
		// @{
		$this->_db = WCConnection::Instance();
		$this->_dbprefix = $wcDatabaseAccess["prefix"];
		// @}
		parent::__construct();
	}
	//
	// Public methods.
	public function hasCronTasks() {
		return true;
	}
	public function runCronTasks($spacer = "") {
		//
		// Setting default value to be returned.
		$retry = false;
		//
		// Tag shortcut.
		$tag = $this->tag();
		//
		// Checking tag status.
		if($tag && $tag->ok()) {
			//
			// Loading global pointers.
			global $wcDefaults;
			//
			// Group shortcut.
			$group = $tag->group();
			//
			// Calculation limit.
			$limit = isset($wcDefaults["class-WCActiveTagFewTags"]["group-limits"][$group->id]) ? $wcDefaults["class-WCActiveTagFewTags"]["group-limits"][$group->id] : $wcDefaults["class-WCActiveTagFewTags"]["limit"];
			//
			// Prompting limit.
			echo "{$spacer}Checking group '{$group->name}' ({$group->id}) with a limit of {$limit} tags:\n";
			//
			// Removing tagged comics.
			// @{
			//
			// Creating a statement to count comic tags.
			// @{
			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[rselect-cmc]";
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "select  mem_comic,\n";
				$query .= "        (count(*)-1) as mem_count,\n";
				$query .= "        min(mem_tag) as mem_tag\n";
				$query .= "from    {$this->_dbprefix}tag_comics\n";
				$query .= "                inner join {$this->_dbprefix}comics\n";
				$query .= "                        on(mem_comic = cmc_id and mem_group = cmc_group)\n";
				$query .= "where   mem_comic in (\n";
				$query .= "                select  mem_comic\n";
				$query .= "                from    {$this->_dbprefix}tag_comics\n";
				$query .= "                where   mem_tag   = :tag\n";
				$query .= "                 and    mem_group = :group)\n";
				$query .= " and    mem_group = :group\n";
				$query .= " and    cmc_lost  = 'N'\n";
				$query .= "group by mem_comic\n";
				$stmt = $this->_db->prepare($stmtId, $query);
			}
			// @}
			//
			// Building database parameters
			$params = array(
				":group" => $group->id,
				":tag" => $tag->id
			);
			//
			// Asking database comic tag's counts.
			if($stmt->execute($params) && $stmt->rowCount() > 0) {
				//
				// Walking over every result.
				foreach($stmt->fetchAll() as $row) {
					//
					// When a comic has more tags than the
					// limit it should not have this tag. Also
					// if it has no tags, it requires another
					// Active tag.
					if($row["mem_count"] > $limit || $row["mem_count"] == 0) {
						//
						// Getting comic.
						$comic = WCComicsHolder::I()->item($row["mem_comic"]);
						//
						// Checking comic status.
						if($comic && $comic->ok() && $comic->group == $group->id) {
							//
							// Removing tag.
							echo "{$spacer}Removing '{$comic->name}' ({$comic->id}[{$comic->directory}]) from '{$tag->name}'\n";
							$tag->removeComic($comic);
							$retry = true;
						}
					}
				}
			}
			// @}
			//
			// Adding tag to comics
			// @{
			//
			// Creating a statement to look for comics with no tags.
			// @{
			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[add-cmc]";
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "select  cmc_id,\n";
				$query .= "        count(*) as mem_count\n";
				$query .= "from    {$this->_dbprefix}tag_comics\n";
				$query .= "                inner join {$this->_dbprefix}comics\n";
				$query .= "                        on(mem_comic = cmc_id and mem_group = cmc_group)\n";
				$query .= "where   mem_comic not in (\n";
				$query .= "                select  mem_comic\n";
				$query .= "                from    {$this->_dbprefix}tag_comics\n";
				$query .= "                where   mem_group = :group\n";
				$query .= "                 and    mem_tag in (:tag, :notag))\n";
				$query .= " and    mem_group = :group\n";
				$query .= " and    cmc_lost  = 'N'\n";
				$query .= "group by mem_comic\n";
				$stmt = $this->_db->prepare($stmtId, $query);
			}
			// @}
			//
			// Building database parameters.
			$params = array(
				":group" => $group->id,
				":tag" => $tag->id,
				":notag" => $this->_noTag->id
			);
			//
			// Requesting entries.
			if($stmt->execute($params)) {
				//
				// Walking over each comic.
				foreach($stmt->fetchAll() as $row) {
					if($row["mem_count"] <= $limit) {
						//
						// Getting comic.
						$comic = WCComicsHolder::I()->item($row["cmc_id"]);
						//
						// Checking comic status.
						if($comic && $comic->ok() && $comic->group == $group->id) {
							//
							// Adding tag.
							echo "{$spacer}Adding '{$comic->name}' ({$comic->id}[{$comic->directory}]) to '{$tag->name}'\n";
							$tag->addComic($comic);
							$retry = true;
						}
					}
				}
			}
			// @}
			//
			// Removing tagged images.
			// @{
			//
			// Creating a statement to count image tags.
			// @{
			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[rselect-img]";
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "select  mem_image,\n";
				$query .= "        (count(*)-1) as mem_count,\n";
				$query .= "        min(mem_tag) as mem_tag\n";
				$query .= "from    {$this->_dbprefix}tag_images\n";
				$query .= "                inner join {$this->_dbprefix}images\n";
				$query .= "                        on(mem_image = img_id and mem_group = img_group)\n";
				$query .= "where   mem_image in (\n";
				$query .= "                select  mem_image\n";
				$query .= "                from    {$this->_dbprefix}tag_images\n";
				$query .= "                where   mem_tag   = :tag\n";
				$query .= "                 and    mem_group = :group)\n";
				$query .= " and    mem_group = :group\n";
				$query .= " and    img_lost  = 'N'\n";
				$query .= "group by mem_image\n";
				$stmt = $this->_db->prepare($stmtId, $query);
			}
			// @}
			//
			// Building database parameters
			$params = array(
				":group" => $group->id,
				":tag" => $tag->id
			);
			//
			// Asking database image tag's counts.
			if($stmt->execute($params) && $stmt->rowCount() > 0) {
				//
				// Walking over every result.
				foreach($stmt->fetchAll() as $row) {
					//
					// When a image has more tags than the
					// limit it should not have this tag. Also
					// if it has no tags, it requires another
					// Active tag.
					if($row["mem_count"] > $limit || $row["mem_count"] == 0) {
						//
						// Getting image.
						$image = WCImagesHolder::I()->item($row["mem_image"]);
						//
						// Checking image status.
						if($image && $image->ok() && $image->group == $group->id) {
							//
							// Removing tag.
							echo "{$spacer}Removing '{$image->name}' ({$image->id}[{$image->directory}]) from '{$tag->name}'\n";
							$tag->removeImage($image);
							$retry = true;
						}
					}
				}
			}
			// @}
			//
			// Adding tag to images
			// @{
			//
			// Creating a statement to look for images with no tags.
			// @{
			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[add-img]";
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "select  img_id,\n";
				$query .= "        count(*) as mem_count\n";
				$query .= "from    {$this->_dbprefix}tag_images\n";
				$query .= "                inner join {$this->_dbprefix}images\n";
				$query .= "                        on(mem_image = img_id and mem_group = img_group)\n";
				$query .= "where   mem_image not in (\n";
				$query .= "                select  mem_image\n";
				$query .= "                from    {$this->_dbprefix}tag_images\n";
				$query .= "                where   mem_group = :group\n";
				$query .= "                 and    mem_tag in (:tag, :notag))\n";
				$query .= " and    mem_group = :group\n";
				$query .= " and    img_lost  = 'N'\n";
				$query .= "group by mem_image\n";
				$stmt = $this->_db->prepare($stmtId, $query);
			}
			// @}
			//
			// Building database parameters.
			$params = array(
				":group" => $group->id,
				":tag" => $tag->id,
				":notag" => $this->_noTag->id
			);
			//
			// Requesting entries.
			if($stmt->execute($params)) {
				//
				// Walking over each image.
				foreach($stmt->fetchAll() as $row) {
					if($row["mem_count"] <= $limit) {
						//
						// Getting image.
						$image = WCImagesHolder::I()->item($row["img_id"]);
						//
						// Checking image status.
						if($image && $image->ok() && $image->group == $group->id) {
							//
							// Adding tag.
							echo "{$spacer}Adding '{$image->name}' ({$image->id}[{$image->directory}]) to '{$tag->name}'\n";
							$tag->addImage($image);
							$retry = true;
						}
					}
				}
			}
			// @}
		} else {
			echo $spacer.WCColorText::ShellRed("Failed").": Tag '{$tag->name}' seems to have issues.\n";
		}

		return $retry;
	}
	public function setTag(WCTag &$tag) {
		global $wcActiveTagsHolder;

		$this->_tag = $tag;
		$group = $tag->group();
		$this->_noTag = $wcActiveTagsHolder->get(WC_ACTIVE_TAG_UNTAGGED, $group);
		if($this->_noTag) {
			$this->_noTag = $this->_noTag->tag();
		}

		return $this->tag();
	}
}
